<!DOCTYPE html>
<html>

<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    
    <meta http-equiv="content-language" content="zh-CN" />
    

    
    <meta name="viewport" content="width=device-width, initial-scale=0.5">
    

    
    <title>遗传算法（待完善）</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.8/clipboard.min.js"></script>
    
    
    
    
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css">

    
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap-theme.min.css">

    <link rel="stylesheet" href="/css/stylesheet.css">
    <link rel="stylesheet" href="/css/home.css">

    
    
        <style type="text/css">
        body { background-color: #fbf6ec;}
        </style>
    
    
                
        
        
            <link rel="stylesheet" href="/css/main.css"/>
        




        
        
        
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/styles/github.min.css"  />
         
        
        <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/highlight.min.js"></script>
        
        
        <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/languages/r.min.js"></script>
        
        <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/languages/yaml.min.js"></script>
        
        <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/languages/latex.min.js"></script>
        
        <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/languages/matlab.min.js"></script>
        
        <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/languages/mathematica.min.js"></script>
        
        <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/languages/julia.min.js"></script>
        
        <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/languages/julia-repl.min.js"></script>
        
        <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/languages/powershell.min.js"></script>
        
        <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/languages/bash.min.js"></script>
        
        <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/languages/shell.min.js"></script>
        
        <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/languages/python.min.js"></script>
        
        <script>hljs.initHighlightingOnLoad();</script>
     <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
          
     <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css" integrity="sha512-+4zCK9k+qNFUR5X+cKL9EIR+ZOhtIloNl9GIKS57V1MyNsYpYcUrUeQc9vNfzsWfV28IaLL3i96P9sdNyeRssA==" crossorigin="anonymous" />
     
     
</head>


<body>
    <script>
        window.addEventListener("resize", resizeThrottler, false);

        var resizeTimeout;
        function resizeThrottler() {
        
        if ( !resizeTimeout ) {
            resizeTimeout = setTimeout(function() {
            resizeTimeout = null;
            actualResizeHandler();
        
            
            }, 66);
        }
        }
        actualResizeHandler()
        function actualResizeHandler() {
                if (/mobile/i.test(navigator.userAgent) || /android/i.test(navigator.userAgent))
                {
                    document.body.classList.add('mobile');
                }else{
                    document.body.classList.remove('mobile');  
                }
    }</script>

    
      
      
            <nav class="navbar navbar-default navbar-static-top" style="opacity: .9" role="navigation">
        <div class="container-fluid">
            
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">

                    <span class="sr-only">Toggle navigation</span>
                    <span class="big-icon icon-bar"></span>
                    <span class="big-icon icon-bar"></span>
                    <span class="big-icon icon-bar"></span>

                </button>
                <a class="navbar-brand" href="/">zsc</a>
            </div>

            <div class="navbar-collapse collapse" id="bs-example-navbar-collapse-1" style="height: auto;">
                <ul class="nav navbar-nav navbar-right" style="font-size: 100%">
                    
                        
                            
                            <li class=""><a href="/about/">About</a></li>
                            
                            <li class=""><a href="/categories/">Categories</a></li>
                            
                            <li class=""><a href="/">Home</a></li>
                            
                            <li class=""><a href="/tags/">Tags</a></li>
                            
                            <li class=""><a href="/issue/">存在的问题</a></li>
                            
                        
                    
                </ul>
            </div>
        </div>
    </nav>










<div class="inner">
    



    <div class="blog-post">
        
                <div>
            <h2 align="center" id = "singe-h2">
                遗传算法（待完善）
                <time>
                    <br>
                    <span> 
                        <i class="fa fa-user-edit" style="color:#888;font-size: 80%;"></i>
                         
                    </span>
                    &nbsp 
                    <span>                 
                        <i class="fa fa-calendar-alt" style="color:#888;font-size: 80%;"></i>
                        2019-02-20 
                    </span>
                </time>
                
                
                <div>
                    <ul class="tags">
                        
                        <span>标签:</span>
                        <li><a class="link" href="/tags/%e6%99%ba%e8%83%bd%e7%ae%97%e6%b3%95"> #智能算法 </a></li>
                        
                        <span> </span>
                        
                    </ul>
                    
                </div>
            </h2>
        </div>
    
        
        <section id="content">
            <h1 id="遗传算法">遗传算法</h1>
<p>遗传算法是模仿自然界生物进化机制发展起来的随机全局搜索和优化方法，本质是一种高效、并行、全局搜索的方法。</p>
<h2 id="基本概念">基本概念</h2>
<h3 id="编码方式"><strong>编码方式</strong></h3>
<p>假设一个具体的问题的解为 $X = (x_1,x_2, \cdots, x_n )$  ，并且每个变量都有取值范围$x_j \in [a_j,b_j]，j=1,2,\cdots,n$.</p>
<table>
<thead>
<tr>
<th style="text-align:left">编码方式</th>
<th>编码</th>
<th>解码</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left">二进制编码</td>
<td>第$j$ 个变量用长度为 $k_j$的二进制编码符号来表示，<br>二进制串编码符号长度与问题所要求的求解进度有关，<br>假设分量$x_j$ 的精度是小数点后4位，则$k_j$的计算公式如下:<br>      $$ \log_2^{(b_j-a_j) \cdot 10^4+1} \le k_j &lt; \log_2^{(b_j-a_j) \cdot 10^4}+1$$<br>一般地，$k_j$都取同一个整数​$k=max{k_j,}$<br></td>
<td>即把二进制串转变为十进制数 <br>假设$x_j$的编码为$c_kc_{k-1}c_{k-2} \cdots c_2c_1$,长度为k,则对应解码公式为:<br>     $$x_j = a_j+(\sum_{i=1}^{k}b_i\cdot 2^{i-1} )\cdot  \frac{b_j-a_j}{2^{k}-1}\ $$</td>
</tr>
<tr>
<td style="text-align:left">格雷码编码</td>
<td>类似二进制编码</td>
<td>类似二进制解码</td>
</tr>
<tr>
<td style="text-align:left">实数编码（也称浮点数编码）</td>
<td>个体的每个基因值用一定范围的一个实数表示，此时染色体长度等于变量个数。</td>
<td>一般不需要解码</td>
</tr>
<tr>
<td style="text-align:left">整数编码</td>
<td>用于特殊的问题（TSP问题）或者其他问题。</td>
<td>一般不需要解码</td>
</tr>
<tr>
<td style="text-align:left">其他编码方式</td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
<p><strong>符号编码</strong>： 二进制编码和格雷码编码 统称符号编码。即单个基因无实际意义。有时候整数编码也叫符号编码。</p>
<p><strong>序号编码</strong>： 实数编码和整数编码。</p>
<p>以下概念都按照二进制编码给出，其余编码几乎都类似。</p>
<h3 id="染色体"><strong>染色体</strong></h3>
<p><strong>染色体</strong>：又称<strong>个体</strong>或者解（即对应问题的解），解$X$中所有分量按二进制编码并依次排列的二进制串称为染色体。</p>
<h3 id="基因">基因</h3>
<p>**基因：**染色体上的每一个二进制位都称为一个基因.</p>
<h3 id="群体">群体</h3>
<p><strong>群体</strong>： 选定的一组解，其中解的个数为群体的规模。</p>
<h3 id="选择">选择</h3>
<p><strong>选择</strong>（又称复制或者选择算子）:  根据各个个体的适应度值，按照一定的规则或者方法从上一代群体中选择出一些优良的个体遗传到下一代群体中。体现了群体中的个体进行优胜劣汰操作。</p>
<p>一般地，选择的优良个体数目 = 种群数目，是从种群中直接选择与种群数目相等的个体生成新种群。若有重复选取的个体则保留。</p>
<h4 id="常见选择算子">常见选择算子</h4>
<table>
<thead>
<tr>
<th>名称</th>
<th>方法</th>
<th>特点</th>
</tr>
</thead>
<tbody>
<tr>
<td>轮盘赌选择<br>(比例选择)<br>常用</td>
<td>每一个个体进入下一代的概率等于它的适应值与整个种群适应度值和的比例。<br>具体操作：<br>1.计算出每个个体的概率，并求出累计分布概率，<br>2. 产生随机数，<br>3.若随机数落入对应的累计分布概率的区间中，则选择该个体。</td>
<td>选择误差较大</td>
</tr>
<tr>
<td>随机竞争选择</td>
<td>1. 利用轮盘赌选择方法， 每次选择两个个体，<br>2. 再从两者中选择适应度高的一个个体。</td>
<td>比轮盘赌选择好</td>
</tr>
<tr>
<td>最佳保留选择</td>
<td>1. 利用轮盘赌选择方法选出（种群数目-1）个个体，<br>2. 再从上一代群体中选择适应度最高的那个个体。</td>
<td>保证迭代终止结果为历代最高适应度个体</td>
</tr>
</tbody>
</table>
<h3 id="交叉"><strong>交叉</strong></h3>
<p><strong>交叉</strong>：又称交叉算子，将群体内的各个个体随机搭配成对，对每一对个体，以某个概率（称为交叉概率，预先给定）交换他们之间的部分染色体。</p>
<p>一般地，交叉次数 = 种群数目 $\times$ 交叉概率。 交叉时直接更新种群，直至达到交叉次数则停止交叉。</p>
<h4 id="常见交叉算子">常见交叉算子：</h4>
<table>
<thead>
<tr>
<th>名称</th>
<th>具体做法</th>
<th>特点</th>
<th>适用编码</th>
</tr>
</thead>
<tbody>
<tr>
<td>单点交叉<br>（符号编码常用）</td>
<td><img src="https://cdn.jsdelivr.net/gh/zscmmm/imgs2208save@master/uPic/2020120922%E5%8D%95%E7%82%B9%E4%BA%A4%E5%8F%89.png" alt=""></td>
<td>标准遗传算法</td>
<td>符号编码</td>
</tr>
<tr>
<td>两点(三点)交叉</td>
<td><img src="https://cdn.jsdelivr.net/gh/zscmmm/imgs2208save@master/uPic/2020120922%E4%B8%A4%E7%82%B9%E4%BA%A4%E5%8F%89.png" alt=""><br><img src="https://cdn.jsdelivr.net/gh/zscmmm/imgs2208save@master/uPic/2020120922%E4%B8%89%E7%82%B9%E4%BA%A4%E5%8F%89.png" alt=""></td>
<td>使用较多</td>
<td>符号编码</td>
</tr>
<tr>
<td>均匀交叉</td>
<td><img src="https://cdn.jsdelivr.net/gh/zscmmm/imgs2208save@master/uPic/2020120922%E5%9D%87%E5%8C%80%E4%BA%A4%E5%8F%89.png" alt=""></td>
<td>无</td>
<td>符号编码</td>
</tr>
<tr>
<td>算术交叉<br> 实数编码常用</td>
<td>算术交叉是指由两个个体的线性组合而产生出两个新的个体。<br>具体交叉公式如下：<br>                                  $$  \begin{cases} X_A^{t+1} = \alpha X_B^{t}+(1-\alpha ) X_{A}^{t} \X_B^{t+1} = \alpha X_A^{t}+(1-\alpha ) X_{B}^{t} \end{cases}$$<br>其中$X_A^{t},X_B^{t} $ 第t次进化时要交叉的个体，$X_A^{t+1},X_B^{t+1}$为交叉产生的新个体， $\alpha $ 为一个参数，可以指定为常数，也可以随机产生(常用),也可以根据进化代数所决定。</td>
<td>无</td>
<td>序号编码</td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
<h3 id="变异">变异</h3>
<p><strong>变异</strong>：又称变异算子，对群体中的每一个个体，以某一概率(称为变异概率，预先给定)改变染色体上的一个或者多个基因。</p>
<h4 id="常用变异算子">常用变异算子</h4>
<table>
<thead>
<tr>
<th>名称</th>
<th>具体做法</th>
<th>特点</th>
<th>使用编码</th>
</tr>
</thead>
<tbody>
<tr>
<td>基本位变异<br>（符号编码常用）</td>
<td>在二进制编码中,<br>1. 对每一个个体，产生一个随机数，<br>2. 若随机数小于变异概率，则此个体准备变异<br>3. 该变异个体随机选取一个基因位，由0变1，或1变0</td>
<td>标准遗传算法</td>
<td>符号编码</td>
</tr>
<tr>
<td>均匀变异</td>
<td>在实数编码中,<br>1. 对每一个个体，产生一个随机数，<br>2. 若随机数小于变异概率，则此个体准备变异<br>3. 用符合某一范围内均匀分布的随机数来替换该基因</td>
<td></td>
<td>序号编码</td>
</tr>
<tr>
<td>非均匀变异</td>
<td>对比与均匀变异，不用均匀分布</td>
<td></td>
<td>序号编码</td>
</tr>
<tr>
<td>高斯变异<br>（实数编码中常用）</td>
<td>在实数编码中,<br/>1. 对每一个个体，产生一个随机数，<br/>2. 若随机数小于变异概率，则此个体准备变异<br/>3. 用正太分布的随机数来替换该基因<br/>具体法则：<br/>3.1 先产生一个随机数$p$用来决定该基因是加还是减一个数.<br/>3.2. 如果随机数$p&lt;0.5$,则$$该基因  +该基因距离该变量上边界的长度 \times[1-p^{ \delta}]$$.<br/>3.3如果随机数$p&gt;=0.5$,则 $$该基因  -该基因距离该变量下边界的长度 \times[1-p^{ \delta}]$$ <br/>其中$\delta = (\dfrac{1-当前种群迭代次数 }{最大迭代次数})^2$<br/>3.4 具体该加该减视情况而定。</td>
<td></td>
<td>序号编码</td>
</tr>
</tbody>
</table>
<h3 id="注意-">**注意： **</h3>
<p><strong>1.根据不同问题选择不同的编码方式，选择、交叉、变异对应的算子一般也是不同的。</strong></p>
<p><strong>2. 编码时初始种群时应该检查每个染色体是否符合解的要求（取值范围或者约束条件），</strong></p>
<p><strong>3.种群进行交叉（变异）操作一定要检查交叉（变异）后的染色体是否符合解的要求，若不满足，应该重新进行交叉（变异），直到交叉（变异）成功为止.</strong></p>
<h2 id="基本步骤">基本步骤</h2>
<p>(1) 根据实际问题确认参数集</p>
<p>(2)根据参数集进行编码，并且生成初始种群P(1)</p>
<p>(3) 通过种群解码得到对应的参数值，并带入目标函数得到适应值。</p>
<p>(4) 群体经过选择、交叉、变异运算后得到下一代群体。</p>
<p>(5)终止条件判断：若达到迭代次数则停止算法，输出群体中的最有解，否则转到(3)</p>
<h2 id="预先设置的参数">预先设置的参数</h2>
<p>群体大小，一般取20~100</p>
<p>终止进化代数, 一般取100~500</p>
<p>交叉概率, 一般取0.4~0.99</p>
<p>变异概率,一般取0.0001~0.1</p>
<h2 id="具体案例分析">具体案例分析</h2>
<p>利用遗传算法求以下问题，并精度为小数点后4位。
$$
\begin{aligned}
\max  f(x_1,x_2) &amp; = 21.5 +x_1sin(4\pi x_1)+x_2sin(20\pi x_2)  \
s.t.  &amp;\begin{cases}
\quad &amp; -3.0 \leq x_1 \leq 12.1 \
&amp; 4.1\leq x_2 \leq 5.8
\end{cases}
\end{aligned}
$$
具体步骤：</p>
<p>假设种群大小为10 ，终止进化代数为100，交叉概率为0.4，变异概率为0.1</p>
<p>(1) 根据实际问题确认参数集，</p>
<p>​	该问题的参数集为 $X=(x_1,x_2)$</p>
<p>(2)根据参数集进行编码，并且生成初始种群P(1),</p>
<p>​	根据其精度要求，利用公式计算出，$x_1，x_2$分别编码成18位、15位二进制串，并生成10个初始种群P(1).</p>
<p>​	具体算法 :<br>
$$
\begin{aligned}
x_1: &amp; 17.2042 = \log_2^{(12.1-(-3.0))\cdot10^4+1} \leq 15 &lt; \log_2^{(12.1-(-3.0))\cdot10^4}+1 =18.2042 \text{, 故取18} \
x_2: &amp; 14.0533=\log_2^{(5.8-4.1)\cdot10^4+1} \leq x_2 &lt; \log_2^{(5.8-4.1)\cdot10^4}+1 = 15.0532 \text{,故取15，}
\end{aligned}
$$</p>
<p>所以该问题的染色体长度为33，即所有变量的二进制长度之和。</p>
<p><strong>但为了方便一般变量$x_2$的长度也为18，故染色体长度为</strong> $36=18 \times 变量个数$.</p>
<p>(3) 通过种群解码得到对应的参数值，并带入目标函数得到适应值。</p>
<p>​	若染色体二进制为<code>111101001110101010'000000010101101010</code>  可解码为$X=(11.446273,4.171908)$ .然后在带入目标函数得到适应值，</p>
<p>记住：有10个染色体，对应10个适应度值</p>
<p>(4) 群体经过选择、交叉、变异运算后得到下一代群体。</p>
<p>选择（轮盘赌选择方法）：  把适应度值进行求和归一化当做概率，用累计概率把区间[0,1]划分成10份，然后产生10个随机数，若随机数落入对应的区间内，则选择该染色体，作为下一代种群（有重复的染色体，不用删除，每个染色体独立）。</p>
<p>交叉（单点交叉）：基于选择产生的染色体，也产生10个随机数，如对应的随机数低于交叉概率，则选择用来交叉，交叉点的位置也是随机的。</p>
<p>变异（基本位变异）： 基于交叉产生的染色体，也产生10个随机数，如对应的随机数低于变异概率，则用来变异，变异点的位置也是随机的。</p>
<p>于是新的一代种群产生了。</p>
<p>(5)终止条件判断：若达到迭代次数则停止算法，输出群体中的最有解，否则转到(3)</p>
<h2 id="连续函数求最小值-遗传算法通用代码二进制编码">连续函数求最小值 遗传算法通用代码(二进制编码)</h2>
<p>需要用到遗传算法工具箱，需要自己配置</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-matlab" data-lang="matlab"><span style="display:flex;"><span><span style="color:#75715e">%% 清空所有</span>
</span></span><span style="display:flex;"><span>clc
</span></span><span style="display:flex;"><span>clear all
</span></span><span style="display:flex;"><span>close all
</span></span><span style="display:flex;"><span><span style="color:#75715e">%% 定义目标函数值--用向量的形式定义方便以后调用</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">%ObjFun = @(x,y)21.5+x.*sin(4*pi.*x)+y.*sin(20*pi.*y);</span>
</span></span><span style="display:flex;"><span>ObjFun = @(X)<span style="color:#f92672">-</span>(<span style="color:#ae81ff">21.5</span><span style="color:#f92672">+</span>X(:,<span style="color:#ae81ff">1</span>)<span style="color:#f92672">.*</span>sin(<span style="color:#ae81ff">4</span><span style="color:#f92672">*</span>pi<span style="color:#f92672">.*</span>X(:,<span style="color:#ae81ff">1</span>))<span style="color:#f92672">+</span>X(:,<span style="color:#ae81ff">2</span>)<span style="color:#f92672">.*</span>sin(<span style="color:#ae81ff">20</span><span style="color:#f92672">*</span>pi<span style="color:#f92672">.*</span>X(:,<span style="color:#ae81ff">2</span>)));
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">%% 定义遗传算法初始参数</span>
</span></span><span style="display:flex;"><span>NIND = <span style="color:#ae81ff">100</span>;  <span style="color:#75715e">% 个体数目，或者种群大小（Number of individual）</span>
</span></span><span style="display:flex;"><span>MAXGEN = <span style="color:#ae81ff">500</span> ;  <span style="color:#75715e">%最大遗传代数 （Maximum number of generation）</span>
</span></span><span style="display:flex;"><span>NVAR = <span style="color:#ae81ff">2</span>; <span style="color:#75715e">% 变量的数目，此处为x1 x2两个变量，所以染色体长度为NVAR * PRECI</span>
</span></span><span style="display:flex;"><span>PRECI = <span style="color:#ae81ff">18</span>; <span style="color:#75715e">% 变量的二进制位数（Precision of variable ）若当某个变量长度不一样时，取所有变量中编码最长的那个, </span>
</span></span><span style="display:flex;"><span>GGAP = <span style="color:#ae81ff">0.9</span>; <span style="color:#75715e">% 代沟(Generation gap )，</span>
</span></span><span style="display:flex;"><span>px = <span style="color:#ae81ff">0.7</span>; <span style="color:#75715e">% 交叉概率</span>
</span></span><span style="display:flex;"><span>pm =<span style="color:#ae81ff">0.01</span>; <span style="color:#75715e">% 变异概率</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">%% 建立区域描述器(Build field descriptor),一种特殊矩阵结构。</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">% 区域描述器结构FieldD =  [len;lb;ub;code;scale;lbin;ubin]</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">%  其中 len 表示染色体长度；</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">%  lb、ub 分别指每个变量使用的下界和上界</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">% code 指明该二进制串是用的什么编码（0代表格雷编码，1代表二进制编码）,常用二进制编码</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">% scale是否使用对数刻度（为0表示算术刻度，1代表对数刻度），常用算术刻度</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">% lbin和ubin 表示是否包含变量的上下边界,0表示不包含，1表示包含 ，</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">%其中rep函数重复某个元素(or矩阵)扩充为指定维度</span>
</span></span><span style="display:flex;"><span>FieldD = [rep([PRECI],[<span style="color:#ae81ff">1</span>,NVAR]);[<span style="color:#f92672">-</span><span style="color:#ae81ff">3.0</span> <span style="color:#ae81ff">4</span>];[<span style="color:#ae81ff">12.1</span> <span style="color:#ae81ff">5.8</span>];[<span style="color:#ae81ff">1</span>,<span style="color:#ae81ff">1</span>];[<span style="color:#ae81ff">0</span> <span style="color:#ae81ff">0</span>];[<span style="color:#ae81ff">1</span> <span style="color:#ae81ff">1</span>];[<span style="color:#ae81ff">1</span> <span style="color:#ae81ff">1</span>]];
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">% 也可以简化为 </span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">%FieldD = [rep([PRECI],[1,NVAR]);rep([-10,15],[1,NVAR]);rep([1;0;1;1]),[1,NVAR]];</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">% rep([PRECI],[1,NVAR])表示为染色体长度 ---对应参数len；</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">% rep([-10,15],[1,NVAR]) 所有变量的上下界 ---- 对应参数lb和ub;</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">% rep([1;0;1;1]),[1,NVAR] 基本的参数</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Chrom = crtbp(NIND,NVAR <span style="color:#f92672">*</span> PRECI);<span style="color:#75715e">% 随机创建初始种群，行代表一个染色体（即个体），NVAR * PRECI 代表染色体长度，每一个变量的长度为PRECI。</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">%% 遗传算法优化</span>
</span></span><span style="display:flex;"><span>gen = <span style="color:#ae81ff">0</span> ; <span style="color:#75715e">% 迭代计数器</span>
</span></span><span style="display:flex;"><span>X = bs2rv(Chrom,FieldD);<span style="color:#75715e">%初始种群转变为十进制数,即解空间</span>
</span></span><span style="display:flex;"><span>ObjV = ObjFun(X);<span style="color:#75715e">%计算初始种群的目标函数值</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">% 优结果的初始跟踪</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">%trace = zeros(3,MAXGEN) ;% 由于本题巧好是两个变量，方便画图，可用此种方法代替，3代表比变量数目多1，每一列代表每一代种群的最有解和对应的适应度值（最后一个）,</span>
</span></span><span style="display:flex;"><span>trace = zeros(<span style="color:#ae81ff">2</span>,MAXGEN);<span style="color:#75715e">%通用方法</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">while</span> gen <span style="color:#f92672">&lt;</span>MAXGEN 
</span></span><span style="display:flex;"><span>    FitnV = ranking(ObjV);  <span style="color:#75715e">%分配适应度 (Assign fitness values),这里求最小值</span>
</span></span><span style="display:flex;"><span>    SelCh = select(<span style="color:#e6db74">&#39;sus&#39;</span>,Chrom,FitnV,GGAP);<span style="color:#75715e">%选择</span>
</span></span><span style="display:flex;"><span>    SelCh = recombin(<span style="color:#e6db74">&#39;xovsp&#39;</span>,SelCh,px);<span style="color:#75715e">% 交叉</span>
</span></span><span style="display:flex;"><span>    SelCh = mut(SelCh,pm); <span style="color:#75715e">%变异</span>
</span></span><span style="display:flex;"><span>    X = bs2rv(SelCh,FieldD);<span style="color:#75715e">% 子代个体转变为十进制数</span>
</span></span><span style="display:flex;"><span>    ObjVSel = ObjFun(X); <span style="color:#75715e">%子代个体的适应度值计算</span>
</span></span><span style="display:flex;"><span>    [Chrom,ObjV]=reins(Chrom,SelCh,<span style="color:#ae81ff">1</span>,<span style="color:#ae81ff">1</span>,ObjV,ObjVSel);<span style="color:#75715e">%重插入子代到父代，得到新种群</span>
</span></span><span style="display:flex;"><span>    gen = gen<span style="color:#f92672">+</span><span style="color:#ae81ff">1</span>;  <span style="color:#75715e">% 迭代计数器更新</span>
</span></span><span style="display:flex;"><span>    [Y,I] = min(ObjV);<span style="color:#75715e">% 获取每代的最有解以及其序号，Y为最优解，I为最有解的个体序号（即种群中所在的行数）</span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">% 对应设置trace = zeros(3,MAXGEN) ;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">%trace(1:2,gen) = X(I,:); % 记下每一代的最有解，因为有两个变量,gen控 制trace矩阵的列,</span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">%trace(3,gen) = Y;%记下每一代的最有解对应的适应度值</span>
</span></span><span style="display:flex;"><span>    trace(<span style="color:#ae81ff">1</span>,gen)= Y;<span style="color:#75715e">%记下每一代的最有解对应的适应度值</span>
</span></span><span style="display:flex;"><span>    trace(<span style="color:#ae81ff">2</span>,gen)= sum(ObjV)<span style="color:#f92672">/</span>length(ObjV);
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">end</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">% 求出最有解</span>
</span></span><span style="display:flex;"><span>[Y,I] = min(ObjV);
</span></span><span style="display:flex;"><span>X(I,:)  <span style="color:#75715e">% 最有解</span>
</span></span><span style="display:flex;"><span>Y       <span style="color:#75715e">%对应的最优适应度值</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">% 画出寻优结果轨迹图</span>
</span></span><span style="display:flex;"><span>figure(<span style="color:#ae81ff">1</span>);
</span></span><span style="display:flex;"><span>plot(trace(<span style="color:#ae81ff">1</span>,:));hold on;
</span></span><span style="display:flex;"><span>plot(trace(<span style="color:#ae81ff">2</span>,:),<span style="color:#e6db74">&#39;-.&#39;</span>);grid;
</span></span><span style="display:flex;"><span>legend(<span style="color:#e6db74">&#39;种群均值的变化&#39;</span>,<span style="color:#e6db74">&#39;解的变化&#39;</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">%% 画出函数图</span>
</span></span><span style="display:flex;"><span>figure(<span style="color:#ae81ff">2</span>);
</span></span><span style="display:flex;"><span>lbx = <span style="color:#f92672">-</span><span style="color:#ae81ff">3.0</span> ; lux = <span style="color:#ae81ff">12.1</span>;
</span></span><span style="display:flex;"><span>lby = <span style="color:#ae81ff">4.1</span> ; luy= <span style="color:#ae81ff">5.8</span>;
</span></span><span style="display:flex;"><span>ezmesh(<span style="color:#e6db74">&#39;21.5+x*sin(4*pi*x)+y*sin(20*pi*y)&#39;</span>,[lbx,lux,lby,luy],<span style="color:#ae81ff">1000</span>)
</span></span><span style="display:flex;"><span>hold on;
</span></span><span style="display:flex;"><span>    
</span></span></code></pre></div><h2 id="连续函数求最小值-遗传算法通用代码实数编码">连续函数求最小值 遗传算法通用代码(实数编码)</h2>
<p>手写</p>
<p>主函数如下:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-matlab" data-lang="matlab"><span style="display:flex;"><span><span style="color:#75715e">%%%%% 不用遗传算法工具箱，手写</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">%% 清空所有</span>
</span></span><span style="display:flex;"><span>clc
</span></span><span style="display:flex;"><span>clear all
</span></span><span style="display:flex;"><span>close all
</span></span><span style="display:flex;"><span><span style="color:#75715e">%% 定义目标函数值--用向量的形式定义方便以后调用</span>
</span></span><span style="display:flex;"><span>ObjFun = @(X)<span style="color:#f92672">-</span>(<span style="color:#ae81ff">21.5</span><span style="color:#f92672">+</span>X(:,<span style="color:#ae81ff">1</span>)<span style="color:#f92672">.*</span>sin(<span style="color:#ae81ff">4</span><span style="color:#f92672">*</span>pi<span style="color:#f92672">.*</span>X(:,<span style="color:#ae81ff">1</span>))<span style="color:#f92672">+</span>X(:,<span style="color:#ae81ff">2</span>)<span style="color:#f92672">.*</span>sin(<span style="color:#ae81ff">20</span><span style="color:#f92672">*</span>pi<span style="color:#f92672">.*</span>X(:,<span style="color:#ae81ff">2</span>)));
</span></span><span style="display:flex;"><span><span style="color:#75715e">%% GA </span>
</span></span><span style="display:flex;"><span>popsize =<span style="color:#ae81ff">100</span>; <span style="color:#75715e">% 种群规模</span>
</span></span><span style="display:flex;"><span>lenchrom =<span style="color:#ae81ff">3</span>  ;<span style="color:#75715e">% 变量字符串长度</span>
</span></span><span style="display:flex;"><span>pc = <span style="color:#ae81ff">0.7</span>;  <span style="color:#75715e">% 交叉概率</span>
</span></span><span style="display:flex;"><span>pm = <span style="color:#ae81ff">0.3</span>;<span style="color:#75715e">% 变异概率</span>
</span></span><span style="display:flex;"><span>maxgen = <span style="color:#ae81ff">100</span>; <span style="color:#75715e">%进化次数</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">% 变量的取值范围</span>
</span></span><span style="display:flex;"><span>popmax =<span style="color:#ae81ff">12</span>;
</span></span><span style="display:flex;"><span>popmin =<span style="color:#f92672">-</span><span style="color:#ae81ff">5</span>;
</span></span><span style="display:flex;"><span>bound = [popmin popmax;popmin popmax;popmin popmax];
</span></span><span style="display:flex;"><span><span style="color:#75715e">%% 产生初始种群</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">for</span> i = <span style="color:#ae81ff">1</span>:popsize
</span></span><span style="display:flex;"><span>    GApop(i,:) = Code(lenchrom,bound);<span style="color:#75715e">%随机产生一个染色体--采用实数编码</span>
</span></span><span style="display:flex;"><span>    fitness(i) = ObjFun(GApop(i,:));<span style="color:#75715e">% 计算该染色体的适应度</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">end</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">% 找到初始种群中最好的染色体和对应的适应度值，并且设置当前的最好染色体和适应度值为全局最好</span>
</span></span><span style="display:flex;"><span>gbest = GApop;  <span style="color:#75715e">%当前种群所有的染色体为个体最佳</span>
</span></span><span style="display:flex;"><span>fitnessgbest=fitness;<span style="color:#75715e">% 当前种群中所有染色体的适应度值为个体最佳适应度</span>
</span></span><span style="display:flex;"><span>[bestfitness,bestindex] = min(fitness);
</span></span><span style="display:flex;"><span>zbest =GApop(bestindex,:);<span style="color:#75715e">% 当前最好的染色体为全局最佳染色体</span>
</span></span><span style="display:flex;"><span>fitnesszbest=bestfitness;<span style="color:#75715e">% 当前最好的染色体对应的适应度值为全局最佳染色体适应度值</span>
</span></span><span style="display:flex;"><span>yy(<span style="color:#ae81ff">1</span>) = fitnesszbest;  <span style="color:#75715e">% 存储每一代的最优适应度值</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">%% 迭代寻优</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">for</span> i = <span style="color:#ae81ff">1</span>:maxgen
</span></span><span style="display:flex;"><span>    GApop = Select(GApop,fitness,popsize);<span style="color:#75715e">% 选择</span>
</span></span><span style="display:flex;"><span>    GApop=Cross(pc,lenchrom,GApop,popsize,bound);<span style="color:#75715e">% 交叉操作 GA </span>
</span></span><span style="display:flex;"><span>    GApop=Mutation(pm,lenchrom,GApop,popsize,[i maxgen],bound);<span style="color:#75715e">% 变异操作 GA</span>
</span></span><span style="display:flex;"><span>    pop=GApop;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">for</span> j = <span style="color:#ae81ff">1</span>:popsize
</span></span><span style="display:flex;"><span>        fitness(j)= ObjFun(pop(j,:));
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">% 个体最有值更新</span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">if</span> fitness(j)<span style="color:#f92672">&lt;</span>fitnessgbest(j)
</span></span><span style="display:flex;"><span>            gbest(j,:) = pop(j,:);
</span></span><span style="display:flex;"><span>            fitnessgbest(j) = fitness(j);
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">end</span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">% 群体最有值更新</span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">if</span> fitness(j) <span style="color:#f92672">&lt;</span>fitnesszbest
</span></span><span style="display:flex;"><span>            zbest= pop(j,:);
</span></span><span style="display:flex;"><span>            fitnesszbest = fitness(j);
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">end</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">end</span>
</span></span><span style="display:flex;"><span>    yy(i<span style="color:#f92672">+</span><span style="color:#ae81ff">1</span>) = fitnesszbest;
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">end</span>
</span></span><span style="display:flex;"><span> 
</span></span><span style="display:flex;"><span><span style="color:#75715e">%% 输出结果</span>
</span></span><span style="display:flex;"><span>disp(<span style="color:#e6db74">&#39;最优值：&#39;</span>)
</span></span><span style="display:flex;"><span>zbest
</span></span><span style="display:flex;"><span>disp(<span style="color:#e6db74">&#39;最优适应度：&#39;</span>)
</span></span><span style="display:flex;"><span>fitnesszbest
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">%% 画图 -- 进化次数与适应度之间的关系图（折线图）</span>
</span></span><span style="display:flex;"><span>figure(<span style="color:#ae81ff">1</span>)
</span></span><span style="display:flex;"><span>plot(yy,<span style="color:#e6db74">&#39;linewidth&#39;</span>,<span style="color:#ae81ff">2</span>);
</span></span><span style="display:flex;"><span>title([<span style="color:#e6db74">&#39;适应度曲线&#39;</span> ,<span style="color:#e6db74">&#39;终止代数=&#39;</span>,num2str(maxgen)]);
</span></span><span style="display:flex;"><span>xlabel(<span style="color:#e6db74">&#39;进化代数&#39;</span>);ylabel(<span style="color:#e6db74">&#39;适应度&#39;</span>);
</span></span><span style="display:flex;"><span>grid on ;
</span></span></code></pre></div><p>染色体编码如下：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-matlab" data-lang="matlab"><span style="display:flex;"><span><span style="color:#66d9ef">function</span> ret = <span style="color:#a6e22e">Code</span>(lenchrom,bound)
</span></span><span style="display:flex;"><span><span style="color:#75715e">% 本函数将变量编码成染色体，用于随机初始化一个种群</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">% lenchrom  input : 染色体长度</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">% bound     input ： 变量的取值范围</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">% ret       output : 染色体的编码值</span>
</span></span><span style="display:flex;"><span>flag = <span style="color:#ae81ff">0</span> ;
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">while</span> flag <span style="color:#f92672">==</span><span style="color:#ae81ff">0</span>
</span></span><span style="display:flex;"><span>    pick = rand(<span style="color:#ae81ff">1</span>,lenchrom);
</span></span><span style="display:flex;"><span>    ret = bound(:,<span style="color:#ae81ff">1</span>)<span style="color:#f92672">&#39;+</span>(bound(:,<span style="color:#ae81ff">2</span>)<span style="color:#f92672">-</span>bound(:,<span style="color:#ae81ff">1</span>))<span style="color:#f92672">&#39;.*</span>pick;<span style="color:#75715e">%线性插值,bound(:,1)表示变量的下界。</span>
</span></span><span style="display:flex;"><span>    flag = test(lenchrom,bound,ret);<span style="color:#75715e">%染色体可行性检查</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">end</span>
</span></span></code></pre></div><p>染色体可行性检查(若有多的约束自己加，也可以加到目标函数中)</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-matlab" data-lang="matlab"><span style="display:flex;"><span><span style="color:#66d9ef">function</span> flag = <span style="color:#a6e22e">test</span>(lenchrom,bound,code)
</span></span><span style="display:flex;"><span><span style="color:#75715e">% lenchrom input : 染色体长度</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">% bound    input : 变量的取值范围</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">% code  output: 染色体的编码值</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">% 初始变量 </span>
</span></span><span style="display:flex;"><span>flag =<span style="color:#ae81ff">1</span>;
</span></span><span style="display:flex;"><span>[n,m] = size(code);
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">for</span> i = <span style="color:#ae81ff">1</span>:n
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> code(i)<span style="color:#f92672">&lt;</span>bound(i,<span style="color:#ae81ff">1</span>) <span style="color:#f92672">||</span> code(i)<span style="color:#f92672">&gt;</span>bound(i,<span style="color:#ae81ff">2</span>)
</span></span><span style="display:flex;"><span>        flag =<span style="color:#ae81ff">0</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">end</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">end</span>
</span></span></code></pre></div><p>选择算子如下：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-matlab" data-lang="matlab"><span style="display:flex;"><span><span style="color:#66d9ef">function</span> ret=<span style="color:#a6e22e">Select</span>(individuals,fitness,sizepop)
</span></span><span style="display:flex;"><span><span style="color:#75715e">% 本函数对每一代种群中的染色体进行选择，以进行后面的交叉和变异 </span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">% individuals input : 种群信息</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">% fitness input : 适应度</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">% sizepop input : 种群规模</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">% ret   output : 经过选择后的种群</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>sumf = cumsum(fitness<span style="color:#f92672">./</span>sum(fitness));<span style="color:#75715e">%累计概率</span>
</span></span><span style="display:flex;"><span>index = [];
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">for</span> i = <span style="color:#ae81ff">1</span>:sizepop
</span></span><span style="display:flex;"><span>    pick = rand ; <span style="color:#75715e">% 产生随机数</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">for</span> j = <span style="color:#ae81ff">1</span>:sizepop
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">if</span> pick <span style="color:#f92672">&lt;</span>= sumf(j)
</span></span><span style="display:flex;"><span>            index =[index j];
</span></span><span style="display:flex;"><span>            <span style="color:#66d9ef">break</span>;
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">end</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">end</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">end</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>individuals = individuals(index,:);
</span></span><span style="display:flex;"><span>fitness=fitness(index);
</span></span><span style="display:flex;"><span>ret = individuals;
</span></span></code></pre></div><p>交叉算子如下：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-matlab" data-lang="matlab"><span style="display:flex;"><span><span style="color:#66d9ef">function</span> ret=<span style="color:#a6e22e">Cross</span>(pcross,lenchrom,chrom,sizepop,bound)
</span></span><span style="display:flex;"><span><span style="color:#75715e">%本函数完成交叉操作</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">% pcorss                input  : 交叉概率</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">% lenchrom              input  : 染色体的长度</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">% chrom                 input  : 染色体群</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">% sizepop               input  : 种群规模</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">% ret                   output : 交叉后的染色体</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">for</span> i=<span style="color:#ae81ff">1</span>:sizepop 
</span></span><span style="display:flex;"><span>    
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">% 随机选择两个染色体进行交叉</span>
</span></span><span style="display:flex;"><span>    pick=rand(<span style="color:#ae81ff">1</span>,<span style="color:#ae81ff">2</span>);
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">while</span> prod(pick)<span style="color:#f92672">==</span><span style="color:#ae81ff">0</span> <span style="color:#75715e">%检查产生的两个随机数是否存在0 </span>
</span></span><span style="display:flex;"><span>        pick=rand(<span style="color:#ae81ff">1</span>,<span style="color:#ae81ff">2</span>);
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">end</span>
</span></span><span style="display:flex;"><span>    index=ceil(pick<span style="color:#f92672">.*</span>sizepop);<span style="color:#75715e">% ceil  向上取整</span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">% 交叉概率决定是否进行交叉</span>
</span></span><span style="display:flex;"><span>    pick=rand;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">while</span> pick<span style="color:#f92672">==</span><span style="color:#ae81ff">0</span>
</span></span><span style="display:flex;"><span>        pick=rand;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">end</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> pick<span style="color:#f92672">&gt;</span>pcross
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">continue</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">end</span>
</span></span><span style="display:flex;"><span>    flag=<span style="color:#ae81ff">0</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">while</span> flag<span style="color:#f92672">==</span><span style="color:#ae81ff">0</span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">% 随机选择交叉位置</span>
</span></span><span style="display:flex;"><span>        pick=rand;
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">while</span> pick<span style="color:#f92672">==</span><span style="color:#ae81ff">0</span>
</span></span><span style="display:flex;"><span>            pick=rand;
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">end</span>
</span></span><span style="display:flex;"><span>        pos=ceil(pick<span style="color:#f92672">.*</span>sum(lenchrom)); <span style="color:#75715e">%随机选择进行交叉的位置，即选择第几个变量进行交叉，</span>
</span></span><span style="display:flex;"><span>        							   <span style="color:#75715e">% 注意：两个染色体交叉的位置相同</span>
</span></span><span style="display:flex;"><span>        pick=rand; <span style="color:#75715e">%交叉开始</span>
</span></span><span style="display:flex;"><span>        v1=chrom(index(<span style="color:#ae81ff">1</span>),pos); 
</span></span><span style="display:flex;"><span>        v2=chrom(index(<span style="color:#ae81ff">2</span>),pos);
</span></span><span style="display:flex;"><span>        chrom(index(<span style="color:#ae81ff">1</span>),pos)=pick<span style="color:#f92672">*</span>v2<span style="color:#f92672">+</span>(<span style="color:#ae81ff">1</span><span style="color:#f92672">-</span>pick)<span style="color:#f92672">*</span>v1;
</span></span><span style="display:flex;"><span>        chrom(index(<span style="color:#ae81ff">2</span>),pos)=pick<span style="color:#f92672">*</span>v1<span style="color:#f92672">+</span>(<span style="color:#ae81ff">1</span><span style="color:#f92672">-</span>pick)<span style="color:#f92672">*</span>v2; <span style="color:#75715e">%交叉结束</span>
</span></span><span style="display:flex;"><span>        flag1=test(lenchrom,bound,chrom(index(<span style="color:#ae81ff">1</span>),:));  <span style="color:#75715e">%检验染色体1的可行性</span>
</span></span><span style="display:flex;"><span>        flag2=test(lenchrom,bound,chrom(index(<span style="color:#ae81ff">2</span>),:));  <span style="color:#75715e">%检验染色体2的可行性</span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">if</span>   flag1<span style="color:#f92672">*</span>flag2<span style="color:#f92672">==</span><span style="color:#ae81ff">0</span>
</span></span><span style="display:flex;"><span>            flag=<span style="color:#ae81ff">0</span>;
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">else</span> flag=<span style="color:#ae81ff">1</span>;
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">end</span>    <span style="color:#75715e">%如果两个染色体不是都可行，则重新交叉</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">end</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">end</span>
</span></span><span style="display:flex;"><span>ret=chrom;
</span></span></code></pre></div><p>变异算子如下：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-matlab" data-lang="matlab"><span style="display:flex;"><span><span style="color:#66d9ef">function</span> ret=<span style="color:#a6e22e">Mutation</span>(pmutation,lenchrom,chrom,sizepop,pop,bound)
</span></span><span style="display:flex;"><span><span style="color:#75715e">% 本函数完成变异操作</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">% pcorss                input  : 变异概率</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">% lenchrom              input  : 染色体长度</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">% chrom                 input  : 染色体群</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">% sizepop               input  : 种群规模</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">% pop                   input  : 当前种群的进化代数和最大的进化代数信息</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">% ret                   output : 变异后的染色体</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">%pm,l       enchrom,GApop,popsize,[i maxgen],bound</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">%pmutation,lenchrom,chrom,sizepop,pop,      bound</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">%pmutation = pm,lenchrom = lenchrom,chrom= GApop,sizepop=popsize,pop=[1 maxgen]</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">for</span> i=<span style="color:#ae81ff">1</span>:sizepop  
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">% 随机选择一个染色体进行变异</span>
</span></span><span style="display:flex;"><span>    pick=rand;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">while</span> pick<span style="color:#f92672">==</span><span style="color:#ae81ff">0</span>
</span></span><span style="display:flex;"><span>        pick=rand;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">end</span>
</span></span><span style="display:flex;"><span>    index=ceil(pick<span style="color:#f92672">*</span>sizepop);
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">% 变异概率决定该轮循环是否进行变异</span>
</span></span><span style="display:flex;"><span>    pick=rand;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> pick<span style="color:#f92672">&gt;</span>pmutation
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">continue</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">end</span>
</span></span><span style="display:flex;"><span>    flag=<span style="color:#ae81ff">0</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">while</span> flag<span style="color:#f92672">==</span><span style="color:#ae81ff">0</span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">% 变异位置</span>
</span></span><span style="display:flex;"><span>        pick=rand;
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">while</span> pick<span style="color:#f92672">==</span><span style="color:#ae81ff">0</span>
</span></span><span style="display:flex;"><span>            pick=rand;
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">end</span>
</span></span><span style="display:flex;"><span>        pos=ceil(pick<span style="color:#f92672">*</span>sum(lenchrom));  <span style="color:#75715e">%随机选择了染色体变异的位置，即选择了第pos个变量进行变异</span>
</span></span><span style="display:flex;"><span>        v=chrom(i,pos); <span style="color:#75715e">%选择第i个染色体的第pos位置的基因（即第pos个变量）</span>
</span></span><span style="display:flex;"><span>        v1=v<span style="color:#f92672">-</span>bound(pos,<span style="color:#ae81ff">1</span>); <span style="color:#75715e">% 计算该基因距离所处变量下界的长度</span>
</span></span><span style="display:flex;"><span>        v2=bound(pos,<span style="color:#ae81ff">2</span>)<span style="color:#f92672">-</span>v;<span style="color:#75715e">% 计算该基因距离所处变量上界的长度</span>
</span></span><span style="display:flex;"><span>        pick=rand; <span style="color:#75715e">%变异开始-- 应该用的是高斯变异</span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">if</span> pick<span style="color:#f92672">&gt;</span><span style="color:#ae81ff">0.5</span>
</span></span><span style="display:flex;"><span>            delta=v2<span style="color:#f92672">*</span>(<span style="color:#ae81ff">1</span><span style="color:#f92672">-</span>pick^((<span style="color:#ae81ff">1</span><span style="color:#f92672">-</span>pop(<span style="color:#ae81ff">1</span>)<span style="color:#f92672">/</span>pop(<span style="color:#ae81ff">2</span>))^<span style="color:#ae81ff">2</span>));
</span></span><span style="display:flex;"><span>            chrom(i,pos)=v<span style="color:#f92672">+</span>delta;
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">else</span>
</span></span><span style="display:flex;"><span>            delta=v1<span style="color:#f92672">*</span>(<span style="color:#ae81ff">1</span><span style="color:#f92672">-</span>pick^((<span style="color:#ae81ff">1</span><span style="color:#f92672">-</span>pop(<span style="color:#ae81ff">1</span>)<span style="color:#f92672">/</span>pop(<span style="color:#ae81ff">2</span>))^<span style="color:#ae81ff">2</span>));
</span></span><span style="display:flex;"><span>            chrom(i,pos)=v<span style="color:#f92672">-</span>delta;
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">end</span>   <span style="color:#75715e">%变异结束</span>
</span></span><span style="display:flex;"><span>        flag=test(lenchrom,bound,chrom(i,:));     <span style="color:#75715e">%检验染色体的可行性</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">end</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">end</span>
</span></span><span style="display:flex;"><span>ret=chrom;
</span></span></code></pre></div><p>算法程序链接（二进制与实数编码）：<a href="/%E9%81%97%E4%BC%A0%E7%AE%97%E6%B3%95matlab.zip">遗传算法</a></p>

        </section>
    </div>
    <br>
    
    




<span id="/md/2019-02-20-%E9%81%97%E4%BC%A0%E7%AE%97%E6%B3%95/" class="leancloud_visitors" data-flag-title="遗传算法（待完善）">
  <span class="post-meta-item-text">文章总阅读量 </span>
  <span class="leancloud-visitors-count"><i class="leancloud-visitors-count"></i></span>次;
  <p></p>
</span>



    

    
    
    <button id="edit-button" class="icon-button" type="button" title="Fork and edit" aria-label="Fork and edit" aria-haspopup="true" aria-expanded="false" aria-controls="edit">
        <i class="fa fa-edit">编辑本文</i>
    </button>
    
    
    

    <br>
    <hr>
    <li style="float:left;list-style:none">
        
        <a class="previous" href="/md/2019-02-19-%E6%A8%A1%E6%8B%9F%E9%80%80%E7%81%AB%E7%AE%97%E6%B3%95/"> 上一篇: 模拟退火算法（待完善）</a>
        
    </li>
    <li style="float:right;list-style:none">
        
        <a class="next" href="/md/2019-04-26-%E8%AE%BA%E6%96%87%E5%86%99%E4%BD%9C%E5%B7%A5%E5%85%B7/"> 下一篇: 学术论文写作工具</a>
        
    </li>
     
    
    <script src="/js/copyCode.js"></script>
    <script src="/js/tooltips.js"></script>
    
   
    <script>
    [].slice.call(document.querySelectorAll('table')).forEach(function(el) {
        var wrapper = document.createElement('div');
        wrapper.className = 'table-area';
        el.parentNode.insertBefore(wrapper, el);
        el.parentNode.removeChild(el);
        wrapper.appendChild(el);
        $("table").wrap("<div class='table-area'></div>");
    })
    </script>

    
<br>
<hr>


<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-111691389-1"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag() { dataLayer.push(arguments); }
  gtag('js', new Date());

  gtag('config', 'UA-111691389-1');
</script>




      
      
      

       
      
      
      <script>
              document.getElementById("edit-button").addEventListener("click", function () {
                  var editWindow = window.open("https:\/\/github.com\/zoushucai\/blogmmm/edit/master/content/md\/2019-02-20-遗传算法.md");
              });</script>
      
          




<script>
  function resizeIframe(obj) {
    obj.style.height = obj.contentWindow.document.body.scrollHeight + 'px';
  } 
</script>



    </style>
    <script type="text/javascript">
    function showdiv(){
        document.getElementById("divtocTableOfContents").style.display="block";
        document.getElementById("strHref").innerHTML="目录收起-";
        document.getElementById('divTableOfContents').style.width="22%";
        document.getElementById('divTableOfContents').style.height="55%";
        document.getElementById('divTableOfContents').style.top="25%";
        document.getElementById('divTableOfContents').style.bottom="5%";
        document.getElementById("strHref").href="javascript:hidediv()";
    }
    function hidediv(){
        document.getElementById("divtocTableOfContents").style.display="none";
        document.getElementById("strHref").innerHTML="目录展开+";
        document.getElementById("strHref").href="javascript:showdiv()";
        document.getElementById('divTableOfContents').style.width="10%";
        document.getElementById('divTableOfContents').style.height="5%";
    }
    </script>
</body>

</html>
</div> 







    <script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/contrib/mathtex-script-type.min.js" integrity="sha384-LJ2FmexL77rmGm6SIpxq7y+XA6bkLzGZEgCywzKOZG/ws4va9fUVu2neMjvc3zdv" crossorigin="anonymous"></script>

    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.css">
    <script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.js"></script>
    <script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/contrib/auto-render.min.js"></script>
    <script>
        document.addEventListener("DOMContentLoaded", function() {
            renderMathInElement(document.body, {
            delimiters: [
                            {left: "$$", right: "$$", display: true},
                            {left: "$", right: "$", display: false},
                            {left: "\\(", right: "\\)", display: false},
                            {left: "\\[", right: "\\]", display: true}
                        ]
            });
        });
    </script>













<br>
<div class="inner">
              
            
          
          
  
          
  
  <div id="vcomments"></div>
  
  <script src="//cdn1.lncld.net/static/js/3.0.4/av-min.js"></script>
  
  <script src='//unpkg.com/valine/dist/Valine.min.js'></script>
  <script type="text/javascript">
    new Valine({
        el: '#vcomments' ,
        appId: 'HfHPKPkLa0cBEDPcdBAHuqMv-gzGzoHsz',
        appKey: 'r5RJAasN8e0mB9sq6y9pEcX0',
        lang:'zh-CN',
        notify:  false , 
        verify:  false  ,
        avatar:'identicon', 
        placeholder: '说点什么吧...',
        visitor:  true 
    });
  </script>

</div>

<br>
<br>
<footer>
    <p style="float:right;margin-right: 5%;margin-top: 0%;">
        &copy; 2022 <a href="https://github.com/zoushucai">zsc</a>
      </p>
</footer>
<br>
<br>


